<p>
  The trading strategy uses VIX futures as a trading vehicle and S&P E-mini for hedging purposes. The spot VIX price data and
  the continuous front contract price of VIX and E-mini S&amp;P500 futures in the daily resolution are from Quandl.
</P>
<div class="section-example-container">
<pre class="python">
def Initialize(self):
    self.SetStartDate(2011, 1, 1)   # Set Start Date
    self.SetEndDate(2018, 9, 1)     # Set End Date
    self.SetCash(10000000)          # Set Strategy Cash
    self.vix = self.AddData(QuandlVix, "CBOE/VIX", Resolution.Daily).Symbol              # Add Quandl VIX price (daily)
    self.vx1 = self.AddData(QuandlFutures, "CHRIS/CBOE_VX1", Resolution.Daily).Symbol    # Add Quandl VIX front month futures data (daily)
    self.es1 = self.AddData(QuandlFutures, "CHRIS/CME_ES1", Resolution.Daily).Symbol     # Add Quandl E-mini S&P500 front month futures data (daily)
    # Add VIX futures contract data
    self.AddFuture(Futures.Indices.VIX).SetFilter(timedelta(0), timedelta(days=180))
    # Add E-mini S&P500 futures contract data
    self.AddFuture(Futures.Indices.SP500EMini).SetFilter(timedelta(0), timedelta(days=180))
</pre>
</div>
<p>
  Futures basis is defined as the difference between the underlying product cash price and futures contract price at a given time.
</P>
\[Basis_t=S_t-F_t\]
<p>
  Where \(S_t\) is the spot VIX price, \(F_t\) is the VIX futures price. The basis is in contango means the futures price is higher than the spot price.
  The opposite of Contango is Backwardation. It refers to the market condition in which the futures price is less than the spot price.
</p>
\[Contango=S_t<F_t\]
\[Backwardation=S_t>F_t\]
<p>
  We select the nearest VIX and E-mini futures with at least ten trading days to maturity in the futures chains.
</P>
<div class="section-example-container">
<pre class="python">
def OnData(self, data):
    # select the nearest VIX and E-mini S&P500 futures with at least 10 trading days to maturity
    # if the front contract expires, roll forward to the next nearest contract
    for chain in data.FutureChains:
        if chain.Key.Value == Futures.Indices.VIX:
            if self.front_VX is None or ((self.front_VX.Expiry-self.Time).days <= 1):
                contracts = list(filter(lambda x: x.Expiry >= self.Time + timedelta(days = 10), chain.Value))
                self.front_VX = sorted(contracts, key = lambda x: x.Expiry)[0]
        if chain.Key.Value == Futures.Indices.SP500EMini:
            if self.front_ES is None or ((self.front_ES.Expiry-self.Time).days <= 1):
                contracts = list(filter(lambda x: x.Expiry >= self.Time + timedelta(days = 10), chain.Value))
                self.front_ES = sorted(contracts, key = lambda x: x.Expiry)[0]
</pre>
</div>
<p>
  While this trading strategy takes advantage of the roll by selling VIX futures at a premium to the VIX and by buying VIX futures at a discount to the VIX,
  it is exposed to the potentially substantial risks associated with adverse moves in the VIX futures curve. However, as the tendency of VIX futures prices to move inversely to equity returns,
  much of this risk can be hedged by open the E-mini S&amp;P 500 futures position in the same direction.
</P>
<p>
  The number of mini-S&amp;P futures contracts to buy or sell per VIX futures contract is based on the hedge ratio estimates.
  The hedge ratios are constructed from regressions of VIX futures price changes on a constant and
  on contemporaneous percentage changes of the front mini-S&amp;P 500 futures contract both alone and
  multiplied by the number of business days that the VIX futures contract is from the settlement, as shown below.
</p>
\[\Delta P^{VX}_t=\beta_0+\beta_1* Return^{ES}_t+\beta_2*(Return^{ES}_t*TimeToSettlement^{VX}_t)+\mu_t\]
<p>
  After we get the parameters \(beta_0\), \(beta_1\) and \(beta_2\), the formula for the hedge ratio is
</P>
\[HR_t=\frac{\beta_1*1000+\beta_2*TimeToSettlement_{t-1}*1000}{0.01*P^{ES}_{t-1}*50}\]
<div class="section-example-container">
<pre class="python">
  def CalculateHedgeRatio(self):
      price_VX = np.array(self.price_VX)
      price_ES = np.array(self.price_ES)
      delta_VX = np.diff(price_VX)
      res_ES = np.diff(price_ES)/price_ES[:-1]*100
      tts = np.array(self.days_to_maturity)[1:]
      df = pd.DataFrame({"delta_VX":delta_VX, "SPRET":res_ES, "product":res_ES*tts}).dropna()
      # remove rows with zero value
      df = df[(df != 0).all(1)]
      y = df['delta_VX'].astype(float)
      X = df[['SPRET', "product"]].astype(float)
      X = sm.add_constant(X)
      model = sm.OLS(y, X).fit()
      beta_1 = model.params[1]
      beta_2 = model.params[2]
      hedge_ratio = abs((1000*beta_1 + beta_2*((self.front_VX.Expiry-self.Time).days)*1000)/(0.01*50*float(self.Securities[self.es1].Price)))
      self.Plot("Trade", "Hedge Ratio", hedge_ratio)
      return hedge_ratio
</pre>
</div>
<p>
  Our daily futures price data is from the continuous front contract. To measure the time to settlement, we import the custom data of the VIX futures expiration dates from 2011 to 2018.
  We populate the date index with the backward fill method to make it easy to calculate the time to settlement.
</P>
<div class="section-example-container">
<pre class="python">
# import the futures expiry calendar
url = "https://www.dropbox.com/s/5k4rbuzfsfn3w0h/expiry.csv?dl=1"
data = self.Download(url).split('\r\n')
expiry = [x.split(',')[1] for x in data][1:]
date = [x.split(',')[0] for x in data][1:]
df_date = pd.DataFrame(expiry, index = date, columns = ['expiry'])
df_date.index = pd.to_datetime(df_date.index)
df_date['expiry'] = pd.to_datetime(df_date['expiry'])
idx = pd.date_range('01-01-2011', '04-19-2019')
# populate the date index and backward fill the dataframe    
return df_date.reindex(idx, method='bfill')
</pre>
</div>
<p>
  To perform the regression, we save the history price in deque list and update the list every day.
</P>
<div class="section-example-container">
<pre class="python">
# the rolling window to save the front month VX future price
self.price_VX = deque(maxlen=252)
# the rolling window to save the front month ES future price
self.price_ES = deque(maxlen=252)
# the rolling window to save the time-to-maturity of the contract
self.days_to_maturity = deque(maxlen=252)
# initialize the deque list
for index, row in df.iterrows():
    self.price_VX.append(row[self.vx1])
    self.price_ES.append(row[self.es1])
    self.days_to_maturity.append((row['expiry']-index).days)
</pre>
</div>

<p>
  The daily roll is defined as the difference between the front VIX futures price and the VIX, divided by the number of business days until the VIX futures contract settles.
  Short VIX futures positions are entered when the VIX futures basis is in contango and the daily roll exceeds 0.10 and
  long VIX futures positions are entered when the VIX futures basis is in backwardation and the daily roll is less than -0.10.
</P>
<div class="section-example-container">
<pre class="python">
# calculate the daily roll
daily_roll = (self.Securities[self.vx1].Price - self.Securities[self.vix].Price)/(self.front_VX.Expiry-self.Time).days
self.Plot("Trade", "VIX", self.Securities[self.vix].Price)
self.Plot("Trade", "VIX Futures", self.Securities[self.vx1].Price)
self.Plot("Trade", "Daily Roll", daily_roll)
if not self.Portfolio[self.front_VX.Symbol].Invested:
    # Short if the contract is in contango with adaily roll greater than 0.10
    if daily_roll > 0.1:
        hedge_ratio = self.CalculateHedgeRatio()
        self.Plot("Trade", "Sell", self.Securities[self.vx1].Price)
        self.SetHoldings(self.front_VX.Symbol, -0.5)
        self.SetHoldings(self.front_ES.Symbol, -0.5*hedge_ratio)
    # Long if the contract is in backwardation with adaily roll less than -0.10
    elif daily_roll < -0.1:
        hedge_ratio = self.CalculateHedgeRatio()
        self.Plot("Trade", "Buy", self.Securities[self.vx1].Price)
        self.SetHoldings(self.front_VX.Symbol, 0.5)
        self.SetHoldings(self.front_ES.Symbol, 0.5*hedge_ratio)
</pre>
</div>
<p>
  Trades are exited when the motivating conditions no longer exist.
  The exit condition is defined as the daily roll being less than 0.05 for short trades and higher than -0.05 VIX futures points for long trades.
  If these exit conditions are not triggered, trades are exited two days before the contract expires.
</P>
<div class="section-example-container">
<pre class="python">
# exit if the daily roll being less than 0.05 if holding short positions
if self.Portfolio[self.front_VX.Symbol].IsShort and daily_roll < 0.05:
    self.Liquidate()
    self.front_VX = None
    self.front_ES = None
    return

# exit if the daily roll being greater than -0.05 if holding long positions
if self.Portfolio[self.front_VX.Symbol].IsLong and daily_roll > -0.05:
    self.Liquidate()
    self.front_VX = None
    self.front_ES = None
    return

if self.front_VX and self.front_ES:
# if these exit conditions are not triggered, trades are exited two days before it expires
if self.Portfolio[self.front_VX.Symbol].Invested and self.Portfolio[self.front_ES.Symbol].Invested:
  if (self.front_VX.Expiry-self.Time).days <=2 or (self.front_ES.Expiry-self.Time).days <=2:
      self.Liquidate()
      self.front_VX = None
      self.front_ES = None
      return
   </pre>
   </div>
